<?php
/**
 * Created by PhpStorm.
 * User: luiz
 * Date: 2019/6/11
 * Time: 20:36
 */

namespace app\api\service;


use app\lib\enum\OrderStatusEnum;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use think\Exception;
use app\api\service\Order as OrderS;
use app\api\modle\Order as OrderM;
use think\Loader;
use think\Log;

Loader::import('WxPay',EXTEND_PATH,'.Api.php');
class Pay
{
    private $orderID;
    private $orderNO;

    function __construct($orderID)
    {
        if(!$orderID)
        {
            throw new Exception('订单号不允许为NULL');
        }
        $this->orderID = $orderID;
    }

    public function pay()
    {
        //订单号根本就不存在
        //订单号和当前用户不匹配
        //订单未被支付
        //进行库存量检测
        $this->checkOrderValid();
        $orderService = new OrderS();
        $status = $orderService->checkOrderStock($this->orderID);
        if(!$status['pass'])
        {
            return $status;
        }
        return $this->makePreOrder($status['orderPrice']);
    }

    private function makePreOrder($totalPrice)
    {
        //openid
        $openid = Token::getCurrentTokenVar('openid');
        if(!$openid)
        {
            throw new Exception();
        }
        $wxOrderData = new \WxPayUnifiedOrder();
        $wxOrderData->SetOut_trade_no($this->orderNO);
        $wxOrderData->SetTrade_type('JSAPI');
        $wxOrderData->SetTotal_fee($totalPrice*100);
        $wxOrderData->SetBody('金润');
        $wxOrderData->SetOpenid($openid);
        $wxOrderData->SetNotify_url(config('secure.pay_back_url'));
       return $this->getPaySignature($wxOrderData);
    }
    private function getPaySignature($wxOrderData)
    {
        $wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
        if($wxOrder['return_code'] != 'SUCCESS' ||
            $wxOrder['result_code'] != 'SUCCESS')
        {
            Log::record($wxOrder,'error');
            Log::record('预订单获取失败','error');
        }
        //prepay_id
        $this->recordPreOrder($wxOrder);
        $signature = $this->sign($wxOrder);
        return(json(mb_convert_encoding($signature, 'UTF-8', 'UTF-8')));

    }

    private function recordPreOrder($wxOrder)
    {
        OrderM::where('id','=',$this->orderID)->update(['prepay_id'=>$wxOrder['prepay_id']]);
    }
    private function checkOrderValid()
    {
        $order =  OrderM::where('id','=',$this->orderID)->find();
        if(!$order)
        {
            throw new OrderException();
        }
        if(!Token::isValidOperate($order->user_id))
        {
            throw new TokenException([
               'msg'=>'订单与用户信息不匹配',
                'errorCode'=>10003
            ]);
        }
        if($order->status != OrderStatusEnum::UNPAID)
        {
            throw new OrderException([
                'msg' => '订单已支付',
                'errorCode' => 80003,
                'code' => 400
            ]);
        }
        $this->orderNO = $order->order_no;
        return true;
    }
    private function sign($wxOrder)
    {
        $str = "PHP";

         $jsApiPayData = new \WxPayJsApiPay();
        // $jsApiPayData->SetAppid(config('app_id'));
        $jsApiPayData->SetAppid(config('wx.app_id'));
         $jsApiPayData->SetTimeStamp((string)time());
        // $rand = md5(time(), mt_rand(0,1000));
         $rand =  substr(md5($str),8,16);
         $jsApiPayData->SetNonceStr($rand);
         $jsApiPayData->SetPackage('prepay_id='.$wxOrder['prepay_id']);
         $jsApiPayData->SetSignType('md5');
         $sign = $jsApiPayData->MakeSign();
         $rawData = $jsApiPayData->GetValues();
         $rawData['paySign'] = $sign;

         unset($rawData['appId']);
         return $rawData;
    }
}